package com.tuzhi.auth.sys.service.impl;

import com.alibaba.fastjson2.JSON;
import com.tuzhi.auth.sys.config.ConstantConfig;
import com.tuzhi.auth.sys.jpa.entity.SysDictionaryEntity;
import com.tuzhi.auth.sys.jpa.repository.SysDictionaryRepo;
import com.tuzhi.auth.sys.service.SysDictionaryService;
import com.tuzhi.base.jpa.healper.QueryHelper;
import com.tuzhi.base.jpa.repository.BaseRepo;
import com.tuzhi.base.redis.MyRedisTemplate;
import com.tuzhi.base.service.impl.AbsBaseService;
import com.tuzhi.util.ListTzUtil;
import com.tuzhi.util.ObjectTzUtil;
import com.tuzhi.util.StringTzUtil;
import org.apache.commons.lang3.exception.ExceptionUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Service
public class SysDictionaryServiceImpl extends AbsBaseService<SysDictionaryEntity, Long> implements SysDictionaryService {

    private static final Logger log = LoggerFactory.getLogger(SysDictionaryServiceImpl.class);

    @Autowired
    SysDictionaryRepo sysDictionaryRepo;

    @Override
    protected BaseRepo getThisRepo() {
        return sysDictionaryRepo;
    }

    @Autowired
    MyRedisTemplate redisCache;

    @Override
    public String find(String dicName) {

        List<SysDictionaryEntity> list = sysDictionaryRepo.findByDicNameAndStatusOrderBySortNum(dicName, 0);

        if (ListTzUtil.isNotEmpty(list)) {
            for (SysDictionaryEntity en : list) {
                if (DATA_TYPE_LIST.equalsIgnoreCase(en.getDataType())) {
                    return JSON.toJSONString(transList(list, LIST_SOURCE_VAL, String.class));
                } else if (DATA_TYPE_MAP.equalsIgnoreCase(en.getDataType())) {
                    return JSON.toJSONString(transMap(list, String.class));
                } else {
                    return en.getDicValue();
                }
            }
        }

        return "{}";
    }

    @Override
    public List<String> findList(String dicName) {
        List<SysDictionaryEntity> list = sysDictionaryRepo.findByDicNameAndStatusOrderBySortNum(dicName, 0);
        return transList(list, LIST_SOURCE_VAL, String.class);
    }

    @Override
    public <T> List<T> findList(String dicName, String type, Class<T> c) {
        List<SysDictionaryEntity> list = sysDictionaryRepo.findByDicNameAndStatusOrderBySortNum(dicName, 0);
        return transList(list, type, c);
    }

    @Override
    public Map<String, String> findMap(String dicName) {
        List<SysDictionaryEntity> list = sysDictionaryRepo.findByDicNameAndStatusOrderBySortNum(dicName, 0);
        return transMap(list, String.class);
    }

    @Override
    public <T> Map<String, T> findMap(String dicName, Class<T> c) {
        List<SysDictionaryEntity> list = sysDictionaryRepo.findByDicNameAndStatusOrderBySortNum(dicName, 0);
        return transMap(list, c);
    }

    private <T> Map<String, T> transMap(List<SysDictionaryEntity> list, Class<T> c) {
        Map<String, T> map = new HashMap<>();
        if (ListTzUtil.isNotEmpty(list)) {
            for (SysDictionaryEntity en : list) {
                try {
                    map.put(en.getDicKey(), ObjectTzUtil.parseObj(en.getDicValue(), c));
                } catch (Exception e) {
                    log.warn("字典类型转换异常!{}", ExceptionUtils.getRootCause(e));
                }
            }
        }
        return map;
    }

    private <T> List<T> transList(List<SysDictionaryEntity> list, String type, Class<T> c) {
        List<T> rs = new ArrayList<>();
        if (ListTzUtil.isNotEmpty(list)) {
            for (SysDictionaryEntity en : list) {
                try {
                    switch (type) {
                        case LIST_SOURCE_KEY:
                            rs.add(ObjectTzUtil.parseObj(en.getDicKey(), c));
                            break;
                        case LIST_SOURCE_VAL:
                            rs.add(ObjectTzUtil.parseObj(en.getDicValue(), c));
                            break;
                    }

                } catch (Exception e) {
                    log.warn("字典类型转换异常!{}", ExceptionUtils.getRootCause(e));
                }
            }
        }
        return rs;
    }

    @Override
    public List<SysDictionaryEntity> listEntityOfDicName(String dicName) {
        QueryHelper.Builder<SysDictionaryEntity> builder = new QueryHelper.Builder<>();
        builder.eq(SysDictionaryEntity::getDicName, dicName);
        builder.eq(SysDictionaryEntity::getStatus, 0);
        return sysDictionaryRepo.findAll(builder.build().getWhereConditionBO());
    }

    @Override
    public String getUniqueValue(String dicName) {
        try {
            String key = ConstantConfig.getDicRedisKey(dicName);
            String value = redisCache.get(key);
            if (StringTzUtil.isBlankNull(value)) {
                SysDictionaryEntity entity = getOneUnique(SysDictionaryEntity::getDicName, dicName);
                if (entity != null) {
                    value = entity.getDicValue();
                    redisCache.set(key, value);
                }
                log.info("从数据库存中读取-key:{},值：{}", dicName, value);
            } else {
                log.info("从redis中读取-key:{},值：{}", dicName, value);
            }
            return value;
        } catch (Exception ex) {
            log.error("读取字典数据异常：{}", ExceptionUtils.getStackTrace(ex));
        }
        return null;
    }

    @Override
    public List<Object> list4DicName(String dicName) {
        try {
            String key = ConstantConfig.getDicRedisKey(dicName);
            List<Object> list = redisCache.getList(key);
            if (list == null || list.isEmpty()) {
                List<SysDictionaryEntity> datas = listEntityOfDicName(dicName);
                if (datas != null) {
                    list = datas.stream().map(SysDictionaryEntity::getDicValue).collect(Collectors.toList());
                    if (list != null && !list.isEmpty()) {
                        redisCache.rightPushAll(key, list);
                    }
                }
                log.info("从数据库存中读取-key:{},值：{}", dicName, list);
            } else {
                log.info("从redis中读取-key:{},值：{}", dicName, list);
            }
            return list;
        } catch (Exception ex) {
            log.error("读取字典数据异常：{}", ExceptionUtils.getStackTrace(ex));
        }
        return null;
    }
}
